home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / mail / pine3.96.tar.gz / pine3.96.tar / pine3.96 / pico / os_win.c < prev    next >
C/C++ Source or Header  |  1996-07-09  |  18KB  |  867 lines

  1. #line 2 "os_win.c"        /* So compiler knows original name of this file.*/
  2. /*
  3.  * $Id: os_win.c,v 4.34 1996/07/09 23:08:44 mikes Exp $
  4.  *
  5.  * Program:    Operating system dependent routines - MS Windows 3.1
  6.  *
  7.  *
  8.  * Tom Unger
  9.  * Networks and Distributed Computing
  10.  * Computing and Communications
  11.  * University of Washington
  12.  * Administration Builiding, AG-44
  13.  * Seattle, Washington, 98195, USA
  14.  * Internet: mikes@cac.washington.edu
  15.  *
  16.  * Please address all bugs and comments to "pine-bugs@cac.washington.edu"
  17.  *
  18.  *
  19.  * Pine and Pico are registered trademarks of the University of Washington.
  20.  * No commercial use of these trademarks may be made without prior written
  21.  * permission of the University of Washington.
  22.  * 
  23.  * Pine, Pico, and Pilot software and its included text are Copyright
  24.  * 1989-1996 by the University of Washington.
  25.  * 
  26.  * The full text of our legal notices is contained in the file called
  27.  * CPYRIGHT, included with this distribution.
  28.  *
  29.  *
  30.  * Notes:
  31.  *      - mouse support added (mss, 921215)
  32.  *
  33.  *  Portions of this code derived from MicroEMACS 3.10:
  34.  *
  35.  *    MSDOS.C:    Operating specific I/O and Spawning functions
  36.  *            under the MS/PCDOS operating system
  37.  *            for MicroEMACS 3.10
  38.  *            (C)opyright 1988 by Daniel M. Lawrence
  39.  *
  40.  */
  41.  
  42. /*#include    <windows.h>*/
  43.  
  44. #include     <stdio.h>
  45. #include    <errno.h>
  46. #include    <setjmp.h>
  47. #include    <time.h>
  48. #include    <fcntl.h>
  49. /*#include    <io.h>*/
  50. /*#include    <bios.h>*/
  51.  
  52. #include    "osdep.h"
  53. #include    "pico.h"
  54. #include    "estruct.h"
  55. #include    "efunc.h"
  56. #include        "edef.h"
  57. #include        "pico.h"
  58. #include    "dos_gen.h"
  59.  
  60. #ifdef    MOUSE
  61.  
  62. #define MOUSE_BUTTONS        3
  63.                      
  64. #endif    /* MOUSE */
  65.  
  66. /*
  67.  * Internal functions...
  68.  */
  69. int timeout = 0;
  70. static int    MapMSKEYtoPK (int c);
  71. static int    ProcessMouse(MEvent *, unsigned int *);
  72. int        ttopen ();
  73. int        ttclose ();
  74.  
  75.  
  76. /*
  77.  * Include generic DOS/Windows routines
  78.  */
  79. #include    "dos_gen.c"
  80.  
  81.  
  82. #define    MARGIN            8    /* size of minimim margin and    */
  83. #define    SCRSIZ            64    /* scroll size for extended lines */
  84. #define    MROW            2    /* rows in menu */
  85.  
  86.  
  87.  
  88. /*
  89.  * Standard terminal interface dispatch table. Fields point to functions
  90.  * that operate the terminal.  All these functions live in mswin.c, but
  91.  * this structure is defined here because it is specific to pico.
  92.  */
  93. TERM    term    = {
  94.         0,
  95.         0,
  96.     MARGIN,
  97.     SCRSIZ,
  98.     MROW,
  99.         ttopen,
  100.         ttclose,
  101.         mswin_getc,
  102.     mswin_putc,
  103.         mswin_flush,
  104.         mswin_move,
  105.         mswin_eeol,
  106.         mswin_eeop,
  107.         mswin_beep,
  108.     mswin_rev
  109. };
  110.  
  111.  
  112. /*
  113.  * mswin_resize - windows specific callback to set pico's internal tables
  114.  *          to new screen dimensions.
  115.  */
  116. int
  117. mswin_resize (row, col)
  118.     int row, col;
  119. {
  120.     resize_pico (row-1, col);
  121.     return (0);
  122. }
  123.  
  124.  
  125. /*
  126.  * ttresize - recompute the screen dimensions if necessary, and then
  127.  *          adjust pico's internal buffers accordingly.
  128.  */
  129. int ttresize ()
  130. {
  131.     int row, col;
  132.  
  133.     mswin_getscreensize(&row, &col);
  134.     resize_pico (row-1, col);
  135. }
  136.  
  137.  
  138. /*
  139.  * This function is called once to set up the terminal device streams.
  140.  */
  141. int
  142. ttopen()
  143. {
  144.     int rows, columns;
  145.  
  146.     
  147.     mswin_getscreensize (&rows, &columns);
  148.     term.t_nrow = rows - 1;
  149.     term.t_ncol = columns;
  150.     term.t_scrsiz = (columns * 2) / 3;
  151.     
  152.     /*
  153.      * Do we implement optimized character insertion and deletion?
  154.      * o_insert() and o_delete()
  155.      */
  156.     inschar  = delchar = FALSE;
  157.     revexist = TRUE;
  158.     
  159.     mswin_setresizecallback (mswin_resize);
  160.     
  161.     
  162.  
  163. #if    MOUSE
  164.     init_mouse();
  165. #else    /* !MOUSE */
  166.     mexist = 0;
  167. #endif    /* MOUSE */
  168.     return(1);
  169. }
  170.  
  171.  
  172. #ifdef    MOUSE
  173. /* 
  174.  * init_mouse - check for and initialize mouse driver...
  175.  */
  176. int
  177. init_mouse()
  178. {
  179.     nbuttons = MOUSE_BUTTONS;
  180.     return (mexist = TRUE);        /* Mouse always exists under windows */
  181. }
  182.  
  183.  
  184. /*
  185.  * mouseon - call made available for programs calling pico to turn ON the
  186.  *           mouse cursor.
  187.  */
  188. void
  189. mouseon()
  190. {
  191. }
  192.  
  193.  
  194. /*
  195.  * mouseoff - call made available for programs calling pico to turn OFF the
  196.  *           mouse cursor.
  197.  */
  198. void
  199. mouseoff()
  200. {
  201. }
  202. #endif
  203.  
  204.  
  205.  
  206. /*
  207.  * This function gets called just before we go back home to the command
  208.  * interpreter.
  209.  */
  210. int
  211. ttclose()
  212. {
  213.     mswin_clearresizecallback (mswin_resize);
  214.     return(1);
  215. }
  216.  
  217.  
  218.  
  219. /*
  220.  * Flush terminal buffer. Does real work where the terminal output is buffered
  221.  * up. A no-operation on systems where byte at a time terminal I/O is done.
  222.  */
  223. int
  224. ttflush()
  225. {
  226.     return(1);
  227. }
  228.  
  229.  
  230.  
  231. /*
  232.  * Read in a key.
  233.  * Do the standard keyboard preprocessing. Convert the keys to the internal
  234.  * character set.  Resolves escape sequences and returns no-op if global
  235.  * timeout value exceeded.
  236.  */
  237. int
  238. GetKey ()
  239. {
  240.     int            ch = 0;
  241.     unsigned int    lch;
  242.     long        timein;
  243.     MEvent        mouse;
  244.     
  245.  
  246.     ch = NODATA;
  247.     timein = time(0L);
  248.  
  249.  
  250.     /*
  251.      * Main character processing loop.
  252.      */
  253.     while(!mswin_charavail()) {
  254.  
  255. #if MOUSE
  256.     /* Check Mouse.  If we get a mouse event, convert to char
  257.      * event and return that. */
  258.     if (checkmouse (&ch,0,0,0)) {
  259.         curwp->w_flag |= WFHARD;
  260.         return (ch);
  261.     }
  262. #endif /* MOUSE */
  263.  
  264.  
  265.     /* Check Timeout. */
  266.     if(time(0L) >= timein+timeout) 
  267.         return(NODATA);
  268.     }
  269.  
  270.     
  271.     return (MapMSKEYtoPK (mswin_getc_fast()));
  272. }
  273.  
  274.  
  275.  
  276. static int
  277. MapMSKEYtoPK (int c)
  278. {
  279.     switch (c) {
  280.     case MSWIN_KEY_UP:        return (K_PAD_UP);
  281.     case MSWIN_KEY_DOWN:        return (K_PAD_DOWN);
  282.     case MSWIN_KEY_RIGHT:        return (K_PAD_RIGHT);
  283.     case MSWIN_KEY_LEFT:        return (K_PAD_LEFT);
  284.     case MSWIN_KEY_SCROLLUPPAGE:
  285.     case MSWIN_KEY_PREVPAGE:    return (K_PAD_PREVPAGE);
  286.     case MSWIN_KEY_SCROLLDOWNPAGE:
  287.     case MSWIN_KEY_NEXTPAGE:    return (K_PAD_NEXTPAGE);
  288.     case MSWIN_KEY_HOME:        return (K_PAD_HOME);
  289.     case MSWIN_KEY_END:        return (K_PAD_END);
  290.     case MSWIN_KEY_DELETE:        return (K_PAD_DELETE);
  291.     case MSWIN_KEY_F1:        return (F1);
  292.     case MSWIN_KEY_F2:        return (F2);
  293.     case MSWIN_KEY_F3:        return (F3);
  294.     case MSWIN_KEY_F4:        return (F4);
  295.     case MSWIN_KEY_F5:        return (F5);
  296.     case MSWIN_KEY_F6:        return (F6);
  297.     case MSWIN_KEY_F7:        return (F7);
  298.     case MSWIN_KEY_F8:        return (F8);
  299.     case MSWIN_KEY_F9:        return (F9);
  300.     case MSWIN_KEY_F10:        return (F10);
  301.     case MSWIN_KEY_F11:        return (F11);
  302.     case MSWIN_KEY_F12:        return (F12);
  303.     case MSWIN_KEY_SCROLLUPLINE:    return (K_SCROLLUPLINE);
  304.     case MSWIN_KEY_SCROLLDOWNLINE:    return (K_SCROLLDOWNLINE);
  305.     case MSWIN_KEY_SCROLLTO:    return (K_SCROLLTO);
  306.     case MSWIN_KEY_NODATA:        return (NODATA);
  307.     }
  308.     
  309.     /* Control keys. */
  310.     if (c < ' ') 
  311.     return (CTRL | (c + '@'));
  312.     
  313.     /* Normal keys. */
  314.     return (c);
  315. }
  316.  
  317.  
  318.  
  319.  
  320.  
  321. #if    MOUSE
  322. /* 
  323.  * checkmouse - Check mouse and return maped command.
  324.  *
  325.  *    EXPORTED to pico.
  326.  *      NOTE: "down", "xxx", and "yyy" aren't used under windows.
  327.  */
  328. int    
  329. checkmouse (unsigned int *ch, int ddd, int xxx, int yyy)
  330. {
  331.     static int    oindex;        /* Index of previous mouse down. */
  332.     int        k;        /* current bit/button of mouse */
  333.     int        mcol;        /* current mouse column */
  334.     int        mrow;        /* current mouse row */
  335.     int        down;        /* TRUE when mouse down event. */
  336.     unsigned long r;
  337.     int        rv = 0;        /* TRUE when we have something to return. */
  338.     MEvent      mouse;
  339.     int        i = 0;
  340.     MENUITEM    *mp;
  341.  
  342.     
  343.     *ch = 0;
  344.     
  345.     /* Mouse installed? */
  346.     if (!mexist)
  347.     return (FALSE);
  348.  
  349.     if (!mswin_getmouseevent (&mouse)) 
  350.     return (FALSE);
  351.  
  352.  
  353.     /* Location of mouse event. */
  354.     mcol = mouse.nColumn;
  355.     mrow = mouse.nRow;
  356.     
  357.     
  358.     
  359.     /* 
  360.      * If there is a tracking function it gets all the mouse events
  361.      * reguardless of where they occur.
  362.      */
  363.     if (mtrack != NULL) {
  364.     r = mtrack (mouse.event, mrow, mcol, mouse.button, mouse.keys);
  365.     if (r & 0xffff){
  366.         *ch = (unsigned) ((r>>16) & 0xffff);
  367.         rv  = TRUE;
  368.     }
  369.     return (rv);
  370.     }
  371.     
  372.  
  373.  
  374.  
  375.     /* Mouse down or up? */
  376.     if (mouse.event == M_EVENT_DOWN) {    /* button down */
  377.     oindex = -1;    /* No Previous mouse down. */
  378.     }
  379.  
  380.  
  381.     /* In special screen region? */
  382.     for(mp = mfunc; mp; mp = mp->next)
  383.       if(mp->action && M_ACTIVE(mrow, mcol, mp))
  384.     break;
  385.  
  386.     if(mp){
  387.  
  388.     r = (*mp->action)(mouse.event, mrow, mcol, mouse.button, mouse.keys);
  389.     if (r & 0xffff){
  390.         *ch = (unsigned) ((r>>16) & 0xffff);
  391.         rv  = TRUE;
  392.     }
  393.     }
  394.     else{
  395.  
  396.     /* In any of the menuitems? */
  397.     while(1){    /* see if we understand event */
  398.         if(i >= 12){
  399.         i = -1;    /* Not Found. */
  400.         break;
  401.         }
  402.  
  403.         if(M_ACTIVE(mrow, mcol, &menuitems[i]))
  404.         break;    /* Found. */
  405.  
  406.         i++;        /* Next. */
  407.     }
  408.  
  409.     /* Now, was that a mouse down or mouse up? */
  410.     if (mouse.event == M_EVENT_DOWN) {    /* button down */
  411.         oindex = i;            /* remember where */
  412.         if(i != -1)            /* invert label */
  413.         invert_label (1, &menuitems[i]);
  414.     }
  415.     else if (mouse.event == M_EVENT_UP) {/* button up */
  416.         if (oindex != -1) {          /* If up in menu item. */
  417.         if (i == oindex){      /* And same item down in. */
  418.             *ch = menuitems[i].val; /* Return menu character. */
  419.             rv = 1;
  420.         }
  421.         }
  422.     }
  423.     }
  424.  
  425.     /* If this is mouse up AND there was a mouse down in a menu item
  426.      * then uninvert that menu item */
  427.     if(mouse.event == M_EVENT_UP && oindex != -1)
  428.       invert_label(0, &menuitems[oindex]);    /* restore label */
  429.  
  430.     return(rv);
  431. }
  432.  
  433.  
  434. /*
  435.  * invert_label - highlight the label of the given menu item.
  436.  */
  437. void
  438. invert_label(state, m)
  439. int state;
  440. MENUITEM *m;
  441. {
  442.     int            i, j, r, c, p;
  443.     char        *lp;
  444.     int            old_state;
  445.     int            wasShown;
  446.     int            col_offset;
  447.  
  448.     if(m->val == mnoop)
  449.       return;
  450.  
  451.   
  452.     mswin_getpos (&r, &c);            /* get cursor position */
  453.     wasShown = mswin_showcursor (0);
  454.     old_state = mswin_getrevstate ();
  455.     /*
  456.      * Leave the command name bold
  457.      */
  458.     col_offset = (state || !(lp=strchr(m->label, ' '))) ? 0 : (lp - m->label);
  459.     (*term.t_move)(m->tl.r, m->tl.c + col_offset);
  460.     (*term.t_rev)(state);
  461.  
  462.     for(i = m->tl.r; i <= m->br.r; i++) {
  463.       for(j = m->tl.c + col_offset; j <= m->br.c; j++) {
  464.         if(i == m->lbl.r && j == m->lbl.c + col_offset){ /* show label?? */
  465.           lp = m->label + col_offset;
  466.           while(*lp && j++ < m->br.c)
  467.             (*term.t_putchar)(*lp++);
  468.  
  469.           continue;
  470.         }
  471.         else
  472.           (*term.t_putchar)(' ');
  473.       }
  474.     }
  475.  
  476.     (*term.t_rev)(old_state);
  477.     mswin_move (r, c);
  478.     mswin_showcursor (wasShown);
  479. }
  480. #endif    /* MOUSE */
  481.  
  482.  
  483.  
  484. /*
  485.  * Called by mswin to scroll text in window in responce to the scrollbar.
  486.  *
  487.  *  Args: cmd - what type of scroll operation.
  488.  *     scroll_pos - paramter for operation.  
  489.  *            used as position for SCROLL_TO operation.
  490.  * 
  491.  *  Returns: TRUE - did the scroll operation.
  492.  *       FALSE - was not able to do the scroll operation.
  493.  */
  494. int
  495. pico_scroll_callback (cmd, scroll_pos)
  496. int    cmd;
  497. long    scroll_pos;
  498. {
  499.     switch (cmd) {
  500.     case MSWIN_KEY_SCROLLUPLINE:
  501.     scrollupline (0, 1);
  502.     break;
  503.  
  504.     case MSWIN_KEY_SCROLLDOWNLINE:
  505.         scrolldownline (0, 1);
  506.     break;
  507.         
  508.     case MSWIN_KEY_SCROLLUPPAGE:
  509.     backpage (0, 1);
  510.     break;
  511.     
  512.     case MSWIN_KEY_SCROLLDOWNPAGE:
  513.     forwpage (0, 1);
  514.     break;
  515.         
  516.     case MSWIN_KEY_SCROLLTO:
  517.     scrollto (0, 0);
  518.     break;
  519.     }
  520.     
  521.     update ();
  522.     return (TRUE);
  523. }
  524.  
  525.  
  526.  
  527. /*
  528.  * Update the scroll range and position. (exported)
  529.  *
  530.  * This is where curbp->b_linecnt is really managed.  With out this function
  531.  * to count the number of lines when needed curbp->b_linecnt will never
  532.  * really be correct.  BUT, this function is only compiled into the 
  533.  * windows version, so b_linecnt will only ever be right in the windows
  534.  * version.  OK for now because that is the only version that
  535.  * looks at b_linecnt.
  536.  */
  537. update_scroll ()
  538. {
  539.     long    scr_pos;
  540.     long    scr_range;
  541.     LINE    *lp;
  542.     static LINE *last_top_line = NULL;
  543.     static long last_scroll_pos = -1;
  544.     
  545.     
  546.     if (ComposerEditing) {
  547.     /* Editing header - don't allow scroll bars. */
  548.     mswin_setscrollrange (0);
  549.     return(0);
  550.     }
  551.        
  552.     
  553.     /*
  554.      * Count the number of lines in the current bufer.  Done when:
  555.      *
  556.      *      when told to recount:           curbp->b_linecnt == -1
  557.      *      when the top line changed:      curwp->w_linep != last_top_line
  558.      *  when we don't know the scroll pos:  last_scroll_pos == -1
  559.      *
  560.      * The first line in the list is a "place holder" line and is not
  561.      * counted.  The list is circular, when we return the to place
  562.      * holder we have reached the end.
  563.      */
  564.     if(curbp->b_linecnt == -1 || curwp->w_linep != last_top_line
  565.        || last_scroll_pos == -1) {
  566.     scr_range = 0;
  567.     scr_pos = 0;
  568.     for (lp = lforw (curbp->b_linep); lp != curbp->b_linep; 
  569.          lp = lforw (lp)) {
  570.         if (lp == curwp->w_linep)
  571.               scr_pos = scr_range;
  572.  
  573.         ++scr_range;
  574.     }
  575.  
  576.     curbp->b_linecnt = scr_range;
  577.     last_scroll_pos = scr_pos;
  578.     last_top_line = curwp->w_linep;
  579.     }
  580.  
  581.     /*
  582.      * Set new scroll range and position.
  583.      */
  584.     mswin_setscrollrange (curbp->b_linecnt - 1);
  585.     mswin_setscrollpos (last_scroll_pos);
  586.     return (0);
  587. }
  588.  
  589.  
  590.  
  591.  
  592. /*
  593.  * alt_editor - fork off an alternate editor for mail message composition
  594.  *
  595.  */
  596. int
  597. alt_editor(int f, int n)
  598. {
  599.     char   eb[NLINE];                /* buf holding edit command */
  600.     char   *fn;                    /* tmp holder for file name */
  601.     char    errbuf[128];
  602.     char   *writetmp();
  603.     int       status;
  604.     int       done;
  605.     int       rc;
  606.  
  607.  
  608.     if(Pmaster == NULL)
  609.       return(-1);
  610.  
  611.     if(gmode&MDSCUR){
  612.     emlwrite("Alternate editor not available in restricted mode", NULL);
  613.     return(-1);
  614.     }
  615.  
  616.     if(Pmaster->alt_ed == NULL){
  617.     if(!(gmode&MDADVN)){
  618.         emlwrite("\007Unknown Command",NULL);
  619.         return(-1);
  620.     }
  621.     
  622.     /* Guess which editor they want. */
  623.     if(getenv("EDITOR"))
  624.       strcpy(eb, (char *)getenv("EDITOR"));
  625.     else
  626.       *eb = '\0';
  627.   
  628.     done = FALSE;
  629.     while(!done){
  630.         rc = mlreplyd("Which alternate editor ? ",eb,NLINE,QDEFLT,NULL);
  631.  
  632.         switch(rc){
  633.           case ABORT:
  634.         return(-1);
  635.           case HELPCH:
  636.         emlwrite("no alternate editor help yet", NULL);
  637.  
  638. /* take sleep and break out after there's help */
  639.         sleep(3);
  640.         break;
  641.           case (CTRL|'L'):
  642.         sgarbf = TRUE;
  643.         update();
  644.         break;
  645.           case TRUE:
  646.           case FALSE:            /* does editor exist ? */
  647.         if(*eb == '\0'){        /* leave silently? */
  648.             mlerase();
  649.             return(-1);
  650.         }
  651.  
  652.         done++;
  653.         break;
  654.           default:
  655.         break;
  656.         }
  657.     }
  658.     }
  659.     else
  660.       strcpy(eb, Pmaster->alt_ed);
  661.  
  662.     if((fn=writetmp(0, 1)) == NULL){        /* get temp file */
  663.     emlwrite("Problem writing temp file for alt editor", NULL);
  664.     return(-1);
  665.     }
  666.  
  667.     strcat(eb, " ");
  668.     strcat(eb, fn);
  669.     
  670.     emlwrite("Waiting for alternate editor to finish...", NULL);
  671.     
  672.     status = mswin_exec_and_wait ("alternate editor", eb);
  673.  
  674.     switch (status) {
  675.  
  676.     case 0:
  677.     /*
  678.      * Success:  replace edited text with new text 
  679.      */
  680.     curbp->b_flag &= ~BFCHG;    /* make sure old text gets blasted */
  681.     readin(fn, 0);            /* read new text overwriting old */
  682.     unlink(fn);            /* blast temp file */
  683.     curbp->b_flag |= BFCHG;        /* mark dirty for packbuf() */
  684.     ttopen();            /* reset the signals */
  685.     refresh(0, 1);            /* redraw */
  686.     return(0);
  687.  
  688.     
  689.     /*
  690.      * Possible errors.
  691.      */
  692.     case -1:
  693.     /* Failed to map return from WinExec to a HTASK. */
  694.     emlwrite("Problem finding alternet editor task handle.", NULL);
  695.     return (-1);
  696.     
  697.     case -2:
  698.     /* User decided to abandon the alternate editor.*/
  699.     emlwrite("Alternate editor abandoned.", NULL);
  700.     return (-1);
  701.  
  702.     default:
  703.     mswin_exec_err_msg ("alternate editor", status, errbuf, 128);
  704.     emlwrite (errbuf, NULL);
  705.     return (-1);
  706.     }
  707.     return (-1);
  708. }
  709.  
  710.  
  711. /*
  712.  *
  713.  */
  714. void
  715. pico_config_menu_items (KEYMENU *keymenu)
  716. {
  717.     int        i;
  718.     KEYMENU    *k;
  719.     int        key;
  720.     char    cleanLabel[64];
  721.     char    *rb;
  722.  
  723.     mswin_menuitemclear ();
  724.  
  725.     /* keymenu's seem to be hardcoded at 12 entries. */
  726.     for (i = 0, k = keymenu; i < 12; ++i, ++k) {
  727.     if (k->name != NULL && k->label != NULL && 
  728.         k->menuitem != KS_NONE) {
  729.  
  730.         if (k->name[0] == '^')
  731.         key = CTRL | k->name[1];
  732.         else if (strcmp(k->name, "Ret") == 0) 
  733.         key = '\r';
  734.         else
  735.         key = k->name[0];
  736.  
  737.         key |= MENU;    /* Flag it as comming from a menu selection */
  738.  
  739.         if (k->label[0] == '[' && strchr (k->label, ']') != NULL) {
  740.             strcpy (cleanLabel, &k->label[1]);
  741.         rb = strchr (cleanLabel, ']');
  742.         *rb = '\0';
  743.         mswin_menuitemadd (key, cleanLabel, k->menuitem, 0);
  744.         }
  745.         else
  746.             mswin_menuitemadd (key, k->label, k->menuitem, 0);
  747.     }
  748.     }
  749. }
  750.  
  751.  
  752. /*
  753.  *  bktoshell - suspend and wait to be woken up
  754.  *
  755.  *  NOTE:  Not yet used under WINDOWS.
  756.  */
  757. int
  758. bktoshell()
  759. {
  760.     return (0);
  761. }
  762.  
  763.  
  764. /*
  765.  * P_open - run the given command in a sub-shell returning a file pointer
  766.  *        from which to read the output
  767.  *
  768.  * note:
  769.  *    For OS's other than unix, you will have to rewrite this function.
  770.  *    Hopefully it'll be easy to exec the command into a temporary file, 
  771.  *    and return a file pointer to that opened file or something.
  772.  *
  773.  * xxx Need to figure out how to do this in windows.
  774.  */
  775. FILE *P_open(c)
  776. char *c;
  777. {
  778.     return (NULL);
  779. }
  780.  
  781.  
  782. /*
  783.  * P_close - close the given descriptor
  784.  *
  785.  */
  786. P_close(fp)
  787. FILE *fp;
  788. {
  789. }
  790.  
  791.  
  792.  
  793.  
  794. /*
  795.  * pico_file_browse - Exported version of FileBrowse below.
  796.  */
  797. pico_file_browse(pdata, dir, fn, sz, flags)
  798. PICO *pdata;
  799. char *dir, *fn, *sz;
  800. int   flags;
  801. {
  802.     return(FileBrowse(dir, fn, sz, flags));
  803. }
  804.  
  805.  
  806.  
  807.  
  808.  
  809.  
  810.  
  811. /*
  812.  * FileBrowse - display contents of given directory dir
  813.  *
  814.  *        intput:  
  815.  *             dir points to initial dir to browse.
  816.  *             fn  initial file name. 
  817.  *             flags
  818.  *
  819.  *         returns:
  820.  *                   dir points to currently selected directory (without
  821.  *             trailing seperator character).
  822.  *                   fn  points to currently selected file
  823.  *                   sz  points to size of file if ptr passed was non-NULL
  824.  *
  825.  *                   1 if a file's been selected
  826.  *                   0 if no files seleted
  827.  *                  -1 if there where problems
  828.  */
  829. FileBrowse(dir, fn, sz, flags)
  830. char *dir, *fn, *sz;            /* dir, name and optional size */
  831. int  flags;
  832. {
  833.     struct stat sbuf;
  834.     int            rc;
  835.     char        lfn[NFILEN];
  836.     
  837.     if (flags & FB_SAVE) {
  838.     rc = mswin_savefile (dir, fn, NFILEN);
  839.     }
  840.     else {
  841.     *fn = '\0';                /* No initial file names for 
  842.                          * open. */
  843.     rc = mswin_openfile (dir, fn, NFILEN);
  844.     }
  845.     if (rc == 0) {
  846.     if (sz != NULL) {
  847.         /* build full path to stat file. */
  848.         strcpy (lfn, dir);
  849.         strcat (lfn, S_FILESEP);
  850.         strcat (lfn, fn);
  851.         if (stat (fn, &sbuf) < 0) 
  852.          strcpy (sz, "0");
  853.         else 
  854.          strcpy (sz, prettysz (sbuf.st_size));
  855.     }
  856.     return (1);
  857.     }
  858.     return (0);
  859. }
  860.  
  861.  
  862.  
  863. ResizeBrowser ()
  864. {
  865.     return (0);
  866. }
  867.